package com.shigu.linkage.sdks.requests;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shigu.linkage.sdks.exceptions.LinkageException;
import com.shigu.linkage.sdks.responses.LinkageResponse;
import com.shigu.linkage.sdks.util.HttpSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.TreeMap;

public abstract class LinkageRequest<T extends LinkageResponse>{
//    private final String domain="http://114.55.107.88:8080/thub";
private static final Logger logger = LoggerFactory.getLogger(LinkageRequest.class);
    private final String domain="http://channel.lifewallet.cn";
abstract String selUrl();
    public final static String merchantCode="46533031";
    abstract Class<T> responseClass();

    public T exec() throws LinkageException {
        HttpSender sender = new HttpSender();
        String response= null;
        try {
            response = sender.send(domain+selUrl(),requestData(),"UTF-8", HttpSender.SEND_METHOD.POST);
        } catch (Exception e) {
            logger.error(JSON.toJSONString(this)+":"+e.getMessage());
            throw new LinkageException("通讯异常");
        }
        T res=JSONObject.toJavaObject(JSONObject.parseObject(response), responseClass());
        if (!"0".equals(res.getErrorCode())&&!"000000".equals(res.getErrorCode())) {
            logger.error(JSON.toJSONString(this)+" : "+response);
        }
        return res;
    }

    /**
     * 数据提取
     * @return
     * @throws IntrospectionException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    protected Map<String, String> requestData() throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        Class<? extends Object> clazz = this.getClass();
        Map<String, String> returnMap = new TreeMap<>();
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();
                Object vaule = readMethod.invoke(this, new Object[0]);
                returnMap.put(propertyName, vaule == null ? "" : vaule.toString());
            }
        }
        return returnMap;
    }
}
